'''
Created on 28 sept. 2010
@author: Marc CARRE
@contact: carre.marc@gmail.com
@license: GNU GPLv3
@version: 1.0
'''

import unittest
import re
from DataSetGenerator import DataSetGenerator

class DataSetGeneratorTest(unittest.TestCase):

    def testGenerateFloatSimple(self):
        params = ["x", "y"]
        spaces = {"A":"y>x**3","B":"y<x**3"} 
        numPoints = 10
        filePath = "testFloatSimple.txt"
        g = DataSetGenerator(params, [[-2,2], [-8,8]], spaces, numPoints, "FLOAT", filePath)
        g.generate()
        results = self.readResults(filePath)
        if (len(results) != numPoints):
            self.fail()
        self.assertTrue(self.areResultsCorrectSimple(results, params, spaces))
        
    def testGenerateFloatCategories(self):
        params = ["x", "y"]
        spaces = {"A":"y>x**3","B":"y<x**3"} 
        numPoints = [5, 5]
        filePath = "testFloatCategories.txt"
        g = DataSetGenerator(params, [[-2,2], [-8,8]], spaces, numPoints, "FLOAT", filePath)
        g.generate()
        results = self.readResults(filePath)
        self.assertTrue(self.areResultsCorrectCategories(results, params, spaces, numPoints))

    def testGenerateIntSimple(self):
        params = ["x", "y"]
        spaces = {"A":"y>x**3","B":"y<x**3"} 
        numPoints = 10
        filePath = "testIntSimple.txt"
        g = DataSetGenerator(params, [[-2,2], [-8,8]], spaces, numPoints, "INT", filePath)
        g.generate()
        results = self.readResults(filePath)
        if (len(results) != numPoints):
            self.fail()
        self.assertTrue(self.areResultsCorrectSimple(results, params, spaces))
        
    def testGenerateIntCategories(self):
        params = ["x", "y"]
        spaces = {"A":"y>x**3","B":"y<x**3"} 
        numPoints = [5, 5]
        filePath = "testIntCategories.txt"
        g = DataSetGenerator(params, [[-2,2], [-8,8]], spaces, numPoints, "INT", filePath)
        g.generate()
        results = self.readResults(filePath)
        self.assertTrue(self.areResultsCorrectCategories(results, params, spaces, numPoints))
 
    def readResults(self, filePath):
        results = []
        with open(filePath, 'r') as f:
            for line in f:
                m = re.search("([\[\-0-9\.\, \]]+) : (.+)", line)
                point = eval(m.group(1))
                label = m.group(2)
                results.append( [point, label] )
        return results
    
    def areResultsCorrectSimple(self, results, params, spaces):
        areCorrect = True
        for result in results:
            point = result[0]
            lblPt = result[1]
            values = {}
            for i in range(len(params)):
                values[params[i]] = point[i]
            for (lblSpace, space) in spaces.items():
                if (lblPt == lblSpace):
                    areCorrect = areCorrect and eval(space, values, {})
        return areCorrect
    
    def areResultsCorrectCategories(self, results, params, spaces, numPoints):
        countPoints = [0]*len(numPoints)
        i = 0
        for (lblSpace, space) in spaces.items():
            for result in results:
                if (result[1] == lblSpace):
                    countPoints[i] = countPoints[i] + 1
            i = i + 1
        if (countPoints != numPoints):
            return False
        
        areCorrect = True
        for result in results:
            point = result[0]
            lblPt = result[1]
            values = {}
            for i in range(len(params)):
                values[params[i]] = point[i]
            for (lblSpace, space) in spaces.items():
                if (lblPt == lblSpace):
                    areCorrect = areCorrect and eval(space, values, {})
        return areCorrect

if __name__ == "__main__":
    unittest.main()